package com.lysj.admin.auth.management.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;

import cn.hutool.crypto.digest.BCrypt;
import com.lysj.admin.auth.management.domain.Role;
import com.lysj.admin.auth.management.domain.User;
import com.lysj.admin.auth.management.domain.UserRole;
import com.lysj.admin.auth.management.service.RoleService;
import com.lysj.admin.auth.management.service.UserRoleService;
import com.lysj.admin.auth.management.service.UserService;
import com.lysj.admin.utils.annotation.SystemLog;
import com.lysj.admin.utils.constant.CommonConstant;
import com.lysj.admin.utils.spring.foundation.base.BaseController;
import com.lysj.admin.utils.spring.foundation.pagination.PageVo;
import com.lysj.admin.utils.validation.Validation;
import com.lysj.admin.utils.validation.annotation.Valid;
import com.lysj.admin.utils.validation.domain.BindingResult;
import com.lysj.admin.utils.web.ParamUtil;
import com.lysj.admin.utils.web.Resp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author zk
 * @description 用户表控制层
 * @create 2018-07-25 15:02:19
 **/
@Slf4j
@RestController
@RequestMapping("/auth/user")
public class UserController extends BaseController<User> {

    @Resource
    private UserService userService;
    @Resource
    private RoleService roleService;
    @Resource
    private UserRoleService userRoleService;

    @Override
    public UserService getService() {
        return userService;
    }

    /**
     * @author zk
     * @date 2018-08-13 21:03
     * @Description 查询用户
     */
    @Override
    public Resp list(User entity, PageVo pageVo) {
        Page<User> page = getService().list(entity, pageVo);
        for (User user : page.getContent()) {
            user.setRoles(userRoleService.findUserRoleByUserId(user.getId()));
        }
        return new Resp().success(page);
    }

    /**
     * @author zk
     * @date 2018-08-13 20:20
     * @Description 添加用户
     */
    @PostMapping("/save_user")
    @SystemLog(description = "添加用户")
    public Resp save(@Valid User entity, String[] roleIds) {
        entity.setPassword(BCrypt.hashpw(entity.getPassword()));
        entity = userService.save(entity);
        if (!ParamUtil.isBlank(roleIds)) {
            for (String s : roleIds) {
                if (!roleService.countRoleId(s)) {
                    return new Resp().error(Resp.Status.PARAM_ERROR,"角色信息有误");
                }
                UserRole ur = new UserRole();
                ur.setRoleId(s);
                ur.setUserId(entity.getId());
                userRoleService.save(ur);
            }
        } else {
            List<Role> roles = roleService.findByDefaultRole(true);
            if (!ParamUtil.isBlank(roles)) {
                for (Role role : roles) {
                    UserRole ur = new UserRole();
                    ur.setRoleId(role.getId());
                    ur.setUserId(entity.getId());
                    userRoleService.save(ur);
                }
            }
        }
        return new Resp().success("添加成功");
    }

    /**
     * @author zk
     * @date 2018-08-13 21:08
     * @Description 修改用户
     */
    @PostMapping("/update_user")
    @SystemLog(description = "修改用户")
    public Resp update(User entity, String[] roleIds) {
        User user = userService.findOne(entity.getId());
        if (user == null) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "查无此用户");
        }
        //获取Hutool拷贝实例
        CopyOptions copyOptions = CopyOptions.create();
        //忽略为null值得属性
        copyOptions.setIgnoreNullValue(true);
        //进行属性拷贝
        BeanUtil.copyProperties(entity, user, copyOptions);
        //对实体类中的@validation注解进行校验
//        Message message = new Message("password", Pattern.class).add("username", Unique.class);
//        Medusa medusa = Message.getMsg(user, message.getMap());
//        if (!medusa.isFlag()) {
//            return new Resp(Resp.PARAM_ERROR, medusa.getMessage());
//        }
        Set<String> ignoreProperties = new HashSet<>();
        ignoreProperties.add("username");
        ignoreProperties.add("password");
        BindingResult bindingResult = Validation.valid(user,ignoreProperties);
        if(!bindingResult.isFlag()){
            return new Resp().error(Resp.Status.PARAM_ERROR,bindingResult.getMessage().get(0));
        }
        userRoleService.deleteByUserId(user.getId());
        if(!ParamUtil.isBlank(roleIds)){
            for (String s : roleIds) {
                if (!roleService.countRoleId(s)) {
                    return new Resp().error(Resp.Status.PARAM_ERROR, "角色信息有误");
                }
                UserRole ur = new UserRole();
                ur.setRoleId(s);
                ur.setUserId(entity.getId());
                userRoleService.save(ur);
            }
        }

        return new Resp().success("修改成功");

    }

    /**
     * @author zk
     * @date 2018-08-13 20:41
     * @Description 修改密码
     */
    @PostMapping("/modify_password")
    @SystemLog(description = "修改密码")
    public Resp modifyPassword(String id, String password, String newPassword) {
        if(ParamUtil.isBlank(password)){
            return new Resp().error(Resp.Status.PARAM_ERROR, "请填写旧密码");
        }
        if(ParamUtil.isBlank(newPassword)){
            return new Resp().error(Resp.Status.PARAM_ERROR, "请填写新密码");
        }
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "查无此用户");
        }
        if (user.getDelFlag().equals(CommonConstant.DEL_FLAG)) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "该用户已被禁用");
        }
        if (!BCrypt.checkpw(password,user.getPassword())) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "密码错误");
        }
        if (!newPassword.matches("/^[a-zA-Z0-9_-]{6,20}$/")) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "密码应为英文、数字、下划线组成的6-20位字符");
        }
        user.setPassword(BCrypt.hashpw(newPassword));
        userService.save(user);
        return new Resp().success("修改成功");
    }

    /**
     * @author zk
     * @date 2018-08-13 21:00
     * @Description 禁用用户
     */
    @PostMapping("/disable")
    public Resp disable(String id) {
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "查无此用户");
        }
        if (user.getDelFlag().equals(CommonConstant.DEL_FLAG)) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "该用户已被禁用");
        }
        user.setDelFlag(CommonConstant.DEL_FLAG);
        userService.save(user);
        return new Resp().success("禁用成功");
    }

    /**
     * @author zk
     * @date 2018-08-13 21:00
     * @Description 启用用户
     */
    @PostMapping("/enable")
    public Resp enable(String id) {
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "查无此用户");
        }
        if (user.getDelFlag().equals(CommonConstant.NORMAL_FLAG)) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "该用户已启用");
        }
        user.setDelFlag(CommonConstant.NORMAL_FLAG);
        userService.save(user);
        return new Resp().success("启用成功");
    }

    @PostMapping("/reset_password")
    @SystemLog(description = "重置密码")
    public Resp resetPassword(String id) {
        User user = userService.findOne(id);
        if (user == null) {
            return new Resp().error(Resp.Status.PARAM_ERROR, "查无此用户");
        }
        user.setPassword(BCrypt.hashpw("123456"));
        userService.save(user);
        return new Resp().success("密码已重置为：123456");
    }

    @Override
    public Resp delete(String[] ids) {
        return null;
    }

    @Override
    public Resp logicalDel(String[] ids) {
        return null;
    }
}
